﻿// Copyright (c) .NET Foundation and Contributors. Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.

using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;

namespace Roslynator.CSharp.Refactorings;

internal static class CopyAttributeArgumentRefactoring
{
    public static void ComputeRefactoring(RefactoringContext context, AttributeArgumentListSyntax argumentList)
    {
        if (!context.Span.IsEmpty)
            return;

        AttributeArgumentSyntax argument = GetArgument(context, argumentList);

        if (argument is null)
            return;

        context.RegisterRefactoring(
            "Copy argument",
            ct => RefactorAsync(context.Document, argument, ct),
            RefactoringDescriptors.CopyArgument);
    }

    private static AttributeArgumentSyntax GetArgument(RefactoringContext context, AttributeArgumentListSyntax argumentList)
    {
        SeparatedSyntaxList<AttributeArgumentSyntax> arguments = argumentList.Arguments;

        foreach (AttributeArgumentSyntax argument in arguments)
        {
            if (argument.IsMissing
                && context.Span.Contains(argument.Span))
            {
                int index = arguments.IndexOf(argument);

                if (index > 0
                    && !arguments[index - 1].IsMissing)
                {
                    return argument;
                }
            }
        }

        return null;
    }

    public static Task<Document> RefactorAsync(
        Document document,
        AttributeArgumentSyntax argument,
        CancellationToken cancellationToken = default)
    {
        var argumentList = (AttributeArgumentListSyntax)argument.Parent;

        int index = argumentList.Arguments.IndexOf(argument);

        AttributeArgumentSyntax previousArgument = argumentList.Arguments[index - 1]
            .WithTriviaFrom(argument);

        return document.ReplaceNodeAsync(argument, previousArgument, cancellationToken);
    }
}
